package com.forcht.server.handler;

import com.forcht.common.domain.GroupChat;
import com.forcht.common.domain.Response;
import com.forcht.common.domain.ResponseHeader;
import com.forcht.common.domain.User;
import com.forcht.common.enumeration.ResponseCode;
import com.forcht.common.enumeration.ResponseType;
import com.forcht.common.util.ProtostuffUtil;
import com.forcht.server.dao.GroupChatDao;
import com.forcht.server.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by forcht on 2018/4/11.
 */
@Component
public class UserHandler {

    @Autowired
    private UserDao userDao;

    @Autowired
    private GroupChatDao groupChatDao;
    //已登录的用户
    private Map<String, SocketChannel> onlineUsers;

    public UserHandler() {
        onlineUsers = new ConcurrentHashMap<>();
    }

    /**
     * 获取用户的socket通道
     *
     * @param username
     * @return
     */
    public SocketChannel getUserSocketChannel(String username) {
        return onlineUsers.get(username);
    }

    /**
     * 移除用户的socket通道
     *
     * @param username
     */
    public void removeUserSocketChannel(String username) {
        onlineUsers.remove(username);
    }

    /**
     * 用户登录
     *
     * @param socketChannel
     * @param username
     * @param password
     * @return
     */
    public synchronized User login(SocketChannel socketChannel, String username, String password) {
        //获取用于信息
        User user = userDao.selectUserByUsername(username);
        if (user != null) {
            //更新用户的状态
            userDao.updateUserStatus(username, true);
            //获取好友列表
            List<User> users = userDao.selectFriendsByUsername(username);
            user.setFriends(users);
            //获取群聊列表
            List<GroupChat> groupChats = groupChatDao.selectGroupChatsByUsername(username);
            user.setGroupChats(groupChats);
            //保存已登录的用户的通道
            onlineUsers.put(username, socketChannel);
        }
        return user;
    }

    /**
     * 用户下线
     *
     * @param username
     * @return
     */
    public synchronized boolean logout(String username) {
        //更新用户的状态
        userDao.updateUserStatus(username, false);
        //移除用户通道
        removeUserSocketChannel(username);
        return true;
    }

    /**
     * 通知好友上线/下线
     *
     * @param user
     * @param responseCode
     */
    public void broadcast(User user, ResponseCode responseCode) {
        String username = user.getUsername();
        List<User> friends = user.getFriends();
        Response response = Response.builder().header(ResponseHeader.builder().
                responseType(ResponseType.HINT).
                responseCode(responseCode).
                timestamp(new Date()).build()).body(username.getBytes()).build();
        for (int i = 0; i < friends.size(); i++) {
            SocketChannel socketChannel = getUserSocketChannel(friends.get(i).getUsername());
            if (socketChannel != null) {
                try {
                    socketChannel.write(ByteBuffer.wrap(ProtostuffUtil.serialize(response)));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 通知好友上线/下线
     *
     * @param username
     * @param responseCode
     */
    public void broadcast(String username, ResponseCode responseCode) {
        List<User> users = userDao.selectFriendsByUsername(username);
        User user = User.builder().username(username).friends(users).build();
        broadcast(user, responseCode);
    }

}
